package org.social.gm;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.social.controller.AccountQueryServer;
import org.social.controller.ActivityServer;
import org.social.controller.DictionaryServer;
import org.social.controller.FunctionSwitchServer;
import org.social.controller.GMServer;
import org.social.controller.GameInterceptServer;
import org.social.controller.GiftCodeServer;
import org.social.controller.MailServer;
import org.social.controller.NoticeServer;
import org.social.controller.PlayerDataServer;
import org.social.controller.ScriptServer;

import com.dal.gm_api.api.IAccount;
import com.dal.gm_api.api.IActivity;
import com.dal.gm_api.api.IDictionary;
import com.dal.gm_api.api.IFunctionSwitch;
import com.dal.gm_api.api.IGameIntercept;
import com.dal.gm_api.api.IGiftCode;
import com.dal.gm_api.api.IMail;
import com.dal.gm_api.api.INotice;
import com.dal.gm_api.api.IPlayerData;
import com.dal.gm_api.api.IScript;
import com.dal.gm_api.api.IServer;
import com.dal.gm_api.msg.HttpRpcRequest;
import com.dal.gm_api.msg.HttpRpcResponse;
import com.dal.gm_api.util.GMException;
import com.dal.gm_api.util.SerializationUtils;
import com.sojoys.artifact.core.IRouter;
import com.sojoys.artifact.exception.AbstractLogicModelException;
import com.sojoys.artifact.third.web.core.NettyHttpContext;

/**
 * @author : DengYing
 * @CreateDate : 2018年1月8日 上午11:12:52
 * @Description ：Please describe this document
 */
public class RpcHandler implements IRouter{
	Map<String, Object> handlerMap = new HashMap<String, Object>();

	{
		handlerMap.put(IMail.class.getName(),new MailServer());
		handlerMap.put(IAccount.class.getName(),new AccountQueryServer());
		handlerMap.put(IServer.class.getName(),new GMServer());
		handlerMap.put(IGameIntercept.class.getName(),new GameInterceptServer());
		handlerMap.put(IPlayerData.class.getName(),new PlayerDataServer());
		handlerMap.put(IGiftCode.class.getName(),new GiftCodeServer());
		handlerMap.put(IFunctionSwitch.class.getName(),new FunctionSwitchServer());
		handlerMap.put(INotice.class.getName(),new NoticeServer());
		handlerMap.put(IActivity.class.getName(),new ActivityServer());
		handlerMap.put(IDictionary.class.getName(), new DictionaryServer());
		handlerMap.put(IScript.class.getName(), new ScriptServer());
	}
	@Override
	public boolean call(NettyHttpContext context) throws Exception {
		String rpc = context.getHeader("rpc");
		if (Boolean.TRUE.toString().equals(rpc)) {
			HttpRpcRequest httpRpcRequest = (HttpRpcRequest)SerializationUtils.deserialize(context.body());
			String serviceName = httpRpcRequest.getInterfaceName();
			Object serviceBean = handlerMap.get(serviceName);
			HttpRpcResponse response = new HttpRpcResponse();
			try {
				if (serviceBean == null) {
					throw new RuntimeException(String.format("can not find service bean by key: %s", serviceName));
				}
				// 获取反射调用所需的参数
				Class<?> serviceClass = serviceBean.getClass();
				String methodName = httpRpcRequest.getMethodName();
				Class<?>[] parameterTypes = httpRpcRequest.getParameterTypes();
				Object[] parameters = httpRpcRequest.getParameters();
				
				// 执行反射调用
				Method method = serviceClass.getMethod(methodName, parameterTypes);
				method.setAccessible(true);
	
				
			
				Object obj = method.invoke(serviceBean, parameters);
				response.setResult(obj);
			}catch (Exception e) {
				if (e.getCause() instanceof AbstractLogicModelException) {
					AbstractLogicModelException abstractLogicModelException = (AbstractLogicModelException) e.getCause();
					GMException exc = new GMException(abstractLogicModelException.getCode(), abstractLogicModelException.getMessage());
					exc.setStackTrace(e.getStackTrace());	
					response.setException(exc);
				}else {
					response.setException(e);					
				}
			}
			response.setRequestId(httpRpcRequest.getRequestId());
			context.send(SerializationUtils.serialize(response));

			return true;
		}else {
			return false;
		}
	}

}
